package com.itcast.zk.locker;

import com.itcast.zk.locker.service.ILocker;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>Description: </p>
 * @date 
 * @author 
 * @version 1.0
 * <p>Copyright:Copyright(c)2020</p>
 */
@SpringBootApplication
@ComponentScan(basePackages = {"com.itcast"})
@RestController
@Log4j2
public class LockerApplication {

    @Autowired
    @Qualifier("exclusiveLocker")
    private ILocker exclusiveLocker;

    @Autowired
    @Qualifier("sharedLocker")
    private ILocker SharedLocker;

    /**
     * 锁节点
     */
    private final static String NODE_ORDER = "order";

    public static void main(String[] args) {
        SpringApplication.run(LockerApplication.class, args);
    }

    /**
     * 下单（排它锁实现）
     * @param timeout
     * @return
     */
    @GetMapping("/placeOrder")
    public String placeOrder(Long timeout) {
        String acquireResult = exclusiveLocker.acquireDistributedLockNoWait(NODE_ORDER, null);
        try {
            Thread.sleep(timeout);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }finally {
            if("true".equalsIgnoreCase(acquireResult)) {
                exclusiveLocker.releaseDistributedLock(NODE_ORDER);
            }
        }
        return "true".equalsIgnoreCase(acquireResult) ? "success" : "failure";
    }

    /**
     * 下单（共享锁实现）
     * @param timeout
     * @param type
     * @return
     */
    @GetMapping("/placeOrderShare")
    public String placeOrderShare(Long timeout, String type) {
        String acquireResult = SharedLocker.acquireDistributedLock(NODE_ORDER, type);
        try {
            Thread.sleep(timeout);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }finally {
            if(null != acquireResult) {
                SharedLocker.releaseDistributedLock(acquireResult);
            }
        }
        return null != acquireResult ? "success" : "failure";
    }


}
